home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / MiscKit1.7.1 / MiscKit / Palettes / MiscTabMatrixPalette / MiscTabActionCell.subproj / MiscTabActionCell.m < prev    next >
Text File  |  1995-10-31  |  10KB  |  350 lines

  1. /* MiscTabActionCell.m 
  2.  *
  3.  * By Bill Edney, Sean Hill, Mark Onyschuk, and Art Isbell
  4.  * Copyright (C) 1995.  Use governed by the MiscKit license.
  5.  */
  6.  
  7. #import "MiscTabActionCell.h"
  8.  
  9. #import <appkit/appkit.h>
  10.  
  11. #import <objc/List.h>
  12.  
  13. #import "drawTab.h"    // pswrap that draws tab ends.
  14.  
  15. @implementation MiscTabActionCell
  16.  
  17.  
  18. // Methods Overridden From the Superclass
  19. - initTextCell:(const char *)aString
  20. // Initializes a new instance of the receiver.
  21. {
  22.     [super initTextCell:aString];
  23.  
  24.  // finish the initialization process 
  25.     [self finishInitializing];
  26.  
  27.     return self;
  28. }
  29.  
  30. - awake
  31. // Performs additional intialization of the receiver after reading
  32. // from an NXTypedStream.
  33. {
  34.  // do the superclass' awake method 
  35.     [super awake];
  36.  
  37.  // finish the initializing process 
  38.     [self finishInitializing];
  39.  
  40.     return self;
  41. }
  42.  
  43. - setFont:fontObj
  44. // Sets the receiver's font to <fontObj> and fetches font info used
  45. // during the receiver's display.
  46. {
  47.     NXCoord    lineHeight;
  48.  
  49.  // Do the superclass' init method 
  50.     [super setFont:fontObj];
  51.  
  52.  // Grab the font information for the contents of the cell 
  53.     NXTextFontInfo(fontObj, &ascender, &descender, &lineHeight);
  54.  
  55.  // Set tabHeight to match that in EOF IB's StackView.  This results in a
  56.  // height of 17 for Helvetica 12.
  57.     tabHeight = lineHeight - descender + 5.0;
  58.  
  59.  // Set tabBezierImageWidth to provide reasonable scaling behavior.
  60.     tabBezierImageWidth = tabHeight * 14.0 / 17.0;
  61.  
  62.     return self;
  63. }
  64.  
  65. - drawInside:(const NXRect *)cellFrame inView:controlView
  66. // Draws the receiver inside <cellFrame> in view <controlView>.
  67. {
  68.     NXCoord    halfImageWidth = tabBezierImageWidth / 2.0;
  69.     NXPoint    leftImageOrigin,
  70.             rightImageOrigin;
  71.     
  72.     float    unselectedGray;
  73.     
  74.     NXRect     textFrame,
  75.             lowerBezelFrame;
  76.         
  77.     List    *controlCellList;
  78.     int        indx,
  79.             intImageWidth = (int)(tabBezierImageWidth + 0.5);
  80.  
  81.  // if there are no contents, then punt... 
  82.     if (!contents) {
  83.     return self;
  84.     }
  85.  
  86.     if([Window defaultDepthLimit]<=NX_TwoBitGrayDepth)
  87.         unselectedGray = NX_DKGRAY;
  88.     else
  89.         unselectedGray = 0.5;
  90.  
  91.  
  92.  // if <controlView> is not a kind of Matrix (i.e. in IB)
  93.     if (![controlView isKindOf:[Matrix class]]) {
  94.         [super drawInside:cellFrame inView:controlView];    
  95.         return self;
  96.     }
  97.  
  98.  // set drawing to opaque
  99.     PSsetalpha(1.0);
  100.  
  101.     if (![controlView isBackgroundTransparent]) {
  102.         PSsetgray([controlView backgroundGray]);
  103.         NXRectFill(cellFrame);
  104.     }
  105.  
  106.  // fetch information about ourselves in our Matrix
  107.     controlCellList = [controlView cellList];
  108.     indx = [controlCellList indexOf:self];
  109.         
  110.  
  111.  // set up the lowerBezelFrame that will be used for drawing the bezel
  112.  // at our bottom
  113.     NXSetRect(&lowerBezelFrame,
  114.           NX_X(cellFrame) + halfImageWidth,
  115.           NX_MAXY(cellFrame) - 1.0,
  116.           NX_WIDTH(cellFrame), 1.0);
  117.  
  118.  // set textFrame to cellFrame 
  119.     textFrame = *cellFrame;
  120.  
  121.  // set up the leftImageOrigin 
  122.     leftImageOrigin.x = NX_X(cellFrame);
  123.     leftImageOrigin.y = NX_MAXY(cellFrame);
  124.  
  125.  // if indx is 0 (we are the first cell) 
  126.     if (indx == 0) {
  127.     // if we are selected 
  128.     if ([self isSelected]) {
  129.     // Draw selected left tab bezier at leftImageOrigin.
  130.         Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  131.             intImageWidth, (int)tabHeight, NX_WHITE, NX_LTGRAY);
  132.     } else {
  133.     // Otherwise, draw left tab bezier at leftImageOrigin.
  134.         Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  135.             intImageWidth, (int)tabHeight, NX_LTGRAY,
  136.         unselectedGray);
  137.  
  138.     // subtract a half tabBezierImageWidth from lowerBezelFrame's x 
  139.         lowerBezelFrame.origin.x -= halfImageWidth;
  140.     }
  141.  
  142.     // add a tabBezierImageWidth to textFrame's x 
  143.     textFrame.origin.x += tabBezierImageWidth;
  144.  
  145.      // subtract a tabBezierImageWidth plus half tabBezierImageWidth minus 1.0
  146.      // from textFrame's width
  147.     textFrame.size.width -= tabBezierImageWidth + halfImageWidth - 1.0;
  148.     } else {
  149.     // subtract a half tabBezierImageWidth from leftImageOrigin's x 
  150.     leftImageOrigin.x -= halfImageWidth;
  151.  
  152.     // if the cell to left of us is selected 
  153.     if ([[controlCellList objectAt:indx - 1] isSelected]) {
  154.     // Draw left tab bezier at leftImageOrigin.
  155.         Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  156.             intImageWidth, (int)tabHeight, NX_LTGRAY,
  157.         unselectedGray);
  158.  
  159.     // Draw selected right tab bezier at leftImageOrigin.
  160.         Misc_drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  161.             intImageWidth, (int)tabHeight, NX_BLACK, NX_LTGRAY);
  162.     } else if ([self isSelected]) {
  163.     // otherwise, if we are selected 
  164.  
  165.     // Draw right tab bezier at leftImageOrigin.
  166.     // composite tabEndImage to leftImageOrigin 
  167.         Misc_drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  168.             intImageWidth, (int)tabHeight, NX_BLACK, unselectedGray);
  169.  
  170.     // Draw selected left tab bezier at leftImageOrigin.
  171.         Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  172.             intImageWidth, (int)tabHeight, NX_WHITE, NX_LTGRAY);
  173.     } else {
  174.     // Draw left tab bezier at leftImageOrigin.
  175.         Misc_drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  176.             intImageWidth, (int)tabHeight, NX_LTGRAY,
  177.         unselectedGray);
  178.  
  179.     // Draw right tab bezier at leftImageOrigin.
  180.         Misc_drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  181.             intImageWidth, (int)tabHeight, NX_BLACK, unselectedGray);
  182.  
  183.     // subtract a half tabBezierImageWidth from lowerBezelFrame's x 
  184.         lowerBezelFrame.origin.x -= tabBezierImageWidth;
  185.  
  186.     // add 1.0 to lowerBezelFrame's width 
  187.         lowerBezelFrame.size.width += 1.0;
  188.     }
  189.  
  190.     // add a half tabBezierImageWidth to textFrame's x 
  191.     textFrame.origin.x += halfImageWidth;
  192.  
  193.     // subtract a tabBezierImageWidth minus 1.0 from textFrame's width 
  194.     textFrame.size.width -= tabBezierImageWidth - 1.0;
  195.     }
  196.  
  197.  // if indx is less than controlCellList's count minus 1 then we're
  198.  // not the last cell, and...
  199.     if (indx < [controlCellList count] - 1) {
  200.     // draw the cell to the right of us 
  201.     [controlView drawCell:[controlCellList objectAt:indx + 1]];
  202.     } else {
  203.     // set up the rightImageOrigin 
  204.     rightImageOrigin.x = NX_X(cellFrame) + NX_WIDTH(cellFrame)
  205.       - tabBezierImageWidth;
  206.     rightImageOrigin.y = NX_Y(cellFrame) + NX_HEIGHT(cellFrame);
  207.  
  208.     // if we are selected 
  209.     if ([self isSelected]) {
  210.     // Draw selected right tab bezier at rightImageOrigin.
  211.         Misc_drawRightTabBezier((int)rightImageOrigin.x,
  212.             (int)rightImageOrigin.y, intImageWidth,
  213.         (int)tabHeight, NX_BLACK, NX_LTGRAY);
  214.     } else {
  215.     // Draw right tab bezier at rightImageOrigin.
  216.         Misc_drawRightTabBezier((int)rightImageOrigin.x,
  217.             (int)rightImageOrigin.y, intImageWidth,
  218.         (int)tabHeight, NX_BLACK, unselectedGray);
  219.     }
  220.  
  221.     // subtract a tabBezierImageWidth from textFrame's width 
  222.     textFrame.size.width -= halfImageWidth;
  223.  
  224.     // add a half tabBezierImageWidth to lowerBezelFrame's width 
  225.     lowerBezelFrame.size.width += halfImageWidth;
  226.     }
  227.  
  228.  // erase the cell 
  229.  
  230.  // if we are selected 
  231.     if ([self isSelected]) {
  232.     // set our drawing color to NX_LTGRAY 
  233.     PSsetgray(NX_LTGRAY);
  234.     } else {
  235.     PSsetgray(unselectedGray);
  236.     }
  237.     
  238.     textFrame.size.height = tabHeight;
  239.     textFrame.origin.y = NX_MAXY(cellFrame) - tabHeight;
  240.  
  241.  // fill in textFrame 
  242.     NXRectFill(&textFrame);
  243.  
  244.  // now draw the upper bezel 
  245.  
  246.  // set our drawing color to NX_LTGRAY 
  247.  // if we are selected 
  248.     if ([self isSelected]) {
  249.     // set our drawing color to NX_LTGRAY 
  250.     PSsetgray(NX_WHITE);
  251.     } else {
  252.     PSsetgray(NX_LTGRAY);
  253.     }
  254.  
  255.  // set textFrame's height to 1.0 
  256.     textFrame.size.height = 1.0;
  257.  
  258.  // fill in textFrame 
  259.     NXRectFill(&textFrame);
  260.  
  261.  // now draw the text 
  262.  
  263.     // If we are enabled, draw NX_BLACK, else draw NX_LTGRAY
  264.     if ([self isEnabled])
  265.         PSsetgray(NX_BLACK);
  266.     else
  267.     PSsetgray(NX_LTGRAY);
  268.  
  269.  // draw the cell's contents 
  270.  
  271.     if (NXDrawingStatus == NX_DRAWING && [[self font] screenFont])
  272.     [[[self font] screenFont] set];
  273.     else
  274.     [[self font] set];
  275.  
  276.     // The offsets were empirically set by emulating the StackView used in the
  277.     // EOF IB's File Window.
  278.     PSmoveto(NX_X(&textFrame) + 3.0, NX_Y(&textFrame) + tabHeight - 4.0);
  279.     PSshow(contents);
  280.  
  281.  // if we are not selected 
  282.     if (![self isSelected]) {
  283.     // draw the lower bezel 
  284.  
  285.     // set our drawing color to NX_WHITE 
  286.     PSsetgray(NX_WHITE);
  287.  
  288.     // fill in lowerBezelFrame 
  289.     NXRectFill(&lowerBezelFrame);
  290.     }
  291.     return self;
  292. }
  293.  
  294. - highlight:(const NXRect *)cellFrame inView:aView lit:(BOOL)flag
  295. {
  296.     [super highlight:cellFrame inView:aView lit:flag];
  297.     [self drawInside:cellFrame inView:aView];
  298.     return self;
  299. }
  300.  
  301. - calcCellSize:(NXSize *)theSize inRect:(const NXRect *)aRect
  302. {
  303.     theSize->height = tabHeight;
  304.     theSize->width =  (2*tabBezierImageWidth+
  305.                     [[self font] getWidthOf:[self stringValue]]);
  306.     return self;
  307. }
  308.  
  309. - (BOOL)trackMouse:(NXEvent *)theEvent
  310.             inRect:(const NXRect *)cellFrame
  311.             ofView:controlView
  312. {
  313.     BOOL    boolValue = [super trackMouse:(NXEvent *)theEvent
  314.                                     inRect:(const NXRect *)cellFrame
  315.                                     ofView:controlView];
  316.  
  317.     if (theEvent->type == NX_MOUSEUP)
  318.     {
  319.         [self incrementState];
  320.     }
  321.     
  322.     return boolValue;
  323. }
  324.  
  325. - (BOOL)startTrackingAt:(const NXPoint *)startPoint inView:aView
  326. {
  327.     [aView sendAction];
  328.     return NO;
  329. }
  330.  
  331. // Other Instance Methods 
  332. - finishInitializing
  333. {
  334.  // all text displayed will be in Helvetica, 12 point 
  335.     //[self setFont:[Font newFont:"Helvetica" size:12.0]];
  336.     [self setFont:[self font]];
  337.  
  338.  // send the action on no event; we'll handle sending the event ourselves
  339.      [self sendActionOn:NX_NULLEVENTMASK];
  340.  
  341.     return self;
  342. }
  343.  
  344. // Accessor Methods
  345.  
  346. - (BOOL)isSelected
  347. {
  348.     return (cFlags1.highlighted || cFlags1.state);
  349. }
  350. @end